package com.dlc.shop.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dlc.shop.bean.model.SysAccessKey;
import com.dlc.shop.bean.model.SysAccessMenu;
import com.dlc.shop.common.constants.SegmentIdKey;
import com.dlc.shop.common.enums.SysTypeEnum;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.dao.SysAccessKeyMapper;
import com.dlc.shop.dao.SysAccessMenuMapper;
import com.dlc.shop.service.SegmentService;
import com.dlc.shop.service.SysAccessKeyService;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统访问密钥
 *
 * @author YXF
 * @date 2021-10-19 14:41:38
 */
@Service
@AllArgsConstructor
public class SysAccessKeyServiceImpl extends ServiceImpl<SysAccessKeyMapper, SysAccessKey> implements SysAccessKeyService {

    private final SysAccessKeyMapper sysAccessKeyMapper;
    private final SegmentService segmentService;
    private final SysAccessMenuMapper sysAccessMenuMapper;

    @Override
    public SysAccessKey getBySysAccessKeyId(Long sysAccessKeyId) {
        return sysAccessKeyMapper.selectById(sysAccessKeyId);
    }

    @Override
    @CacheEvict(cacheNames = "sysAccessKey", key = "#sysAccessKey.accessId")
    @Transactional(rollbackFor = Exception.class)
    public void saveSysAccessKey(SysAccessKey sysAccessKey) {
        sysAccessKey.setAccessId(String.valueOf(segmentService.getSegmentId(SegmentIdKey.AUTHORIZATION)));
        Digester sha256 = new Digester(DigestAlgorithm.SHA256);
        sysAccessKey.setAccessKey(sha256.digestHex(sysAccessKey.getAccessId()) + System.currentTimeMillis());
        Date date = new Date();
        sysAccessKey.setCreateTime(date);
        sysAccessKey.setUpdateTime(date);
        save(sysAccessKey);
        if (CollectionUtil.isEmpty(sysAccessKey.getMenuIdList())) {
            return;
        }
        // 保存与菜单关系
        sysAccessMenuMapper.insertAccessKeyAndMenu(sysAccessKey.getSysAccessKeyId(), sysAccessKey.getMenuIdList());
    }

    @Override
    public void resetAccessKey(Long sysAccessKeyId) {
        SysAccessKey sysAccessKey = sysAccessKeyMapper.selectById(sysAccessKeyId);
        if (Objects.isNull(sysAccessKey)) {
            // 此数据已被删除
            throw new YamiShopBindException("yami.shop.data.is.removed");
        }
        Digester sha256 = new Digester(DigestAlgorithm.SHA256);
        sysAccessKey.setAccessKey(sha256.digestHex(sysAccessKey.getAccessId()) + System.currentTimeMillis());
        Date date = new Date();
        sysAccessKey.setUpdateTime(date);
        updateById(sysAccessKey);
    }

    @Override
    @CacheEvict(cacheNames = "sysAccessKey", key = "#sysAccessKey.accessId")
    @Transactional(rollbackFor = Exception.class)
    public void updateSysAccessKey(SysAccessKey sysAccessKey) {
        SysAccessKey accessKey = new SysAccessKey();
        accessKey.setSysAccessKeyId(sysAccessKey.getSysAccessKeyId());
        accessKey.setSysType(sysAccessKey.getSysType());
        accessKey.setUsabilityShopId(sysAccessKey.getUsabilityShopId());
        if(!Objects.equals(sysAccessKey.getSysType(),SysTypeEnum.MULTISHOP.value())){
            accessKey.setUsabilityShopId(0L);
        }
        accessKey.setName(sysAccessKey.getName());
        accessKey.setRemark(sysAccessKey.getRemark());
        accessKey.setUpdateTime(new Date());
        updateById(accessKey);
        //先删除角色与菜单关系
        sysAccessMenuMapper.delete(new LambdaQueryWrapper<SysAccessMenu>().eq(SysAccessMenu::getSysAccessKeyId,sysAccessKey.getSysAccessKeyId()));
        if (CollectionUtil.isEmpty(sysAccessKey.getMenuIdList())) {
            return;
        }
        // 保存与菜单关系
        sysAccessMenuMapper.insertAccessKeyAndMenu(sysAccessKey.getSysAccessKeyId(), sysAccessKey.getMenuIdList());
    }

    @Override
    @CacheEvict(cacheNames = "sysAccessKey", key = "#accessId")
    public void removeCacheById(String accessId) {

    }

    @Override
    @Cacheable(cacheNames = "sysAccessKey", key = "#accessId")
    public SysAccessKey getByAccessIdAndPrems(String accessId) {
        SysAccessKey sysAccessKey = sysAccessKeyMapper.selectOne(new LambdaQueryWrapper<SysAccessKey>().eq(SysAccessKey::getAccessId, accessId));
        if (sysAccessKey == null) {
            return null;
        }
        List<String> premsList;
        // 获取perms
        if(Objects.equals(sysAccessKey.getSysType(),SysTypeEnum.MULTISHOP.value())){
            premsList = sysAccessMenuMapper.queryAllPermsByShopMenu(sysAccessKey.getSysAccessKeyId());
        }else{
            premsList = sysAccessMenuMapper.queryAllPermsBySysMenu(sysAccessKey.getSysAccessKeyId());
        }
        if(CollectionUtil.isEmpty(premsList)){
            return sysAccessKey;
        }
        Set<String> prems = premsList.stream().flatMap((perms) -> {
            if (StrUtil.isBlank(perms)) {
                return null;
            }
            return Arrays.stream(perms.trim().split(StrUtil.COMMA));
        }).collect(Collectors.toSet());
        sysAccessKey.setPrems(prems);
        return sysAccessKey;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByAccessKeyId(Long sysAccessKeyId) {
        removeById(sysAccessKeyId);
        //先删除角色与菜单关系
        sysAccessMenuMapper.delete(new LambdaQueryWrapper<SysAccessMenu>().eq(SysAccessMenu::getSysAccessKeyId,sysAccessKeyId));
    }
}
